/*
 * File:                ErrorDialogTraceListener.cs
 * Authors:             Zachary Benz, Jonathan T. McClain
 * Company:             Sandia National Laboratories
 * Project:             MVC
 *
 * Copyright May 6, 2008, Sandia Corporation.  Under the terms of Contract
 * DE-AC04-94AL85000, there is a non-exclusive license for use of this work by
 * or on behalf of the U.S. Government. Export of this program may require a
 * license from the United States Government. See CopyrightHistory.txt for
 * complete details.
 *
 * Reviewers:
 * Review Date:
 * Review Comments:
 *
 * Revision History:
 *
 * $Log: ErrorDialogTraceListener.cs,v $
 * Revision 1.6  2008/05/06 22:16:03  jtmccl
 * 1. Added an application setting called ErrorDialogPriorityThreshold and
 * updated ErrorDialogTraceListener to only display errors above this
 * threshold.
 * 2. Modified StandardPluginSource to send an Error with priority 50 when
 * appdomain_AssemblyResolve is unable to locate an assembly. This is
 * because it appears to be possible for an assembly to be resolved after
 * this event, making the error less important.
 *
 */

using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;
using Sandia.MVCFramework.Properties;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;

namespace Sandia.MVCFramework.Common
{
    /// <summary>
    /// Custom trace listener that can be used to show an error
    /// dialog to the user when a log entry is written
    /// </summary>
    [ConfigurationElementType(typeof(CustomTraceListenerData))]
    public class ErrorDialogTraceListener: CustomTraceListener
    {
        StringBuilder message = new StringBuilder();        

        /// <summary>
        /// Writes trace information, a data object and event information to the listener specific output.
        /// </summary>
        /// <param name="eventCache">A TraceEventCache object that contains the current process ID, thread ID, and stack trace information</param>
        /// <param name="source">A name used to identify the output, typically the name of the application that generated the trace event</param>
        /// <param name="eventType">One of the TraceEventType values specifying the type of event that has caused the trace</param>
        /// <param name="id">A numeric identifier for the event</param>
        /// <param name="data">The trace data to emit</param>
        public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
        {       
            LogEntry logEntry = data as LogEntry;
            if (logEntry != null && 
                this.Formatter != null)
            {
                // We only display errors above the priority threshold.
                if (logEntry.Priority >= Settings.Default.ErrorDialogPriorityThreshold)
                {
                    WindowHandleWrapper windowHandleWrapper = new WindowHandleWrapper(
                        System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle);
                    MessageBox.Show(windowHandleWrapper, this.Formatter.Format(logEntry),
                        "Error Encountered", MessageBoxButtons.OK,
                        MessageBoxIcon.Exclamation);
                }
            }
            else
            {
                this.WriteLine(data.ToString());
            }
        }

        /// <summary>
        /// Writes the specified message to the listener
        /// </summary>
        /// <param name="message">The message to write</param>
        public override void Write(string message)
        {
            this.message.Append(message);
        }

        /// <summary>
        /// Writes the specified message to the listener
        /// </summary>
        /// <param name="message">The message to write</param>
        public override void WriteLine(string message)
        {
            this.message.Append(message);
            WindowHandleWrapper windowHandleWrapper = new WindowHandleWrapper(
                    System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle);
            MessageBox.Show(windowHandleWrapper, this.message.ToString(), "Error Encountered", 
                MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            this.message = new StringBuilder();
        }
    }
}
